/**
 * https://github.com/freeze-component/vue-popper
 *
 */
//  tools
import Popper from 'popper.js'

// https://popper.js.org/popper-documentation.html
export default {
  props: {
    placement: {
      type: String,
      default: 'bottom'
    },
    boundariesPadding: {
      type: Number,
      default: 5
    },
    reference: Object,
    popper: Object,
    offset: {
      default: 0
    },
    /**
     * #property
     *
     * @name      value
     * @cn        初始是否显示
     * @type      boolean
     * @value     false
     * @description   初始是否显示
     */
    value: {
      type: Boolean,
      default: false
    },
    transition: String,
    /**
     * #property
     *
     * @name      options
     * @cn        自定义 popper.js 的配置项
     * @type      object
     * @bind      must
     * @value     {modifiers: { computeStyle: { gpuAcceleration: false } }}
     * @description   自定义 popper.js 的配置项,具体配置见: https://popper.js.org/popper-documentation.html
     */
    options: {
      type: Object,
      default () {
        return {
          modifiers: {
            computeStyle: {
              gpuAcceleration: false
            }
          }
        }
      }
    }
  },
  data () {
    return {
      visible: this.value
    }
  },
  watch: {
    value: {
      immediate: true,
      handler (val) {
        this.visible = val
      }
    },
    visible (val) {
      if (val) {
        this.updatePopper()
        /**
         * #event
         *
         * @name    popper-show
         * @body
         * @description   弹出框显示时触发
         */
        this.$emit('popper-show')
      } else {
        /**
         * #event
         *
         * @name    popper-hide
         * @body
         * @description   弹出框隐藏时触发
         */
        this.$emit('popper-hide')
      }
    }
  },
  mounted() {
    if (this.visible) {
        this.updatePopper()
    }
  },
  methods: {
    createPopper () {
      if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(this.placement)) {
        return
      }

      const options = this.options
      const popper = this.popper || this.$refs.popper
      const reference = this.reference || this.$refs.reference

      if (!popper || !reference) {
        return
      }

      if (this.popperJS && this.popperJS.hasOwnProperty('destroy')) {
        this.popperJS.destroy()
      }

      options.placement = options.placement || this.placement
      options.modifiers = options.modifiers || {}

      options.modifiers.offset = options.modifiers.offset || this.offset

      options.onCreate = () => {
        this.$nextTick(this.updatePopper)
        this.$emit('created', this)
      }

      this.popperJS = new Popper(reference, popper, options)
    },
    updatePopper () {
      this.popperJS ? this.popperJS.update() : this.createPopper()
    },
    doDestroy () {
      if (this.visible) return
      this.popperJS.destroy()
      this.popperJS = null
    }
  },
  beforeDestroy () {
    if (this.popperJS) {
      this.popperJS.destroy()
    }
  }
}
